﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace KP_CommonLibrary.KP_CommonControls.NumericInput
{
    public delegate void MaskChangingEventHandler(object sender, MaskChangingEventArgs e);
    public delegate void ChangeEventHandler(object sender, ChangeEventArgs e);
    public delegate void ChangingEventHandler(object sender, ChangingEventArgs e);
    public class ChangingEventArgs : CancelEventArgs
    {
        // Fields
        private object newValue;
        private object oldValue;

        // Methods
        public ChangingEventArgs(object oldValue, object newValue)
            : this(oldValue, newValue, false)
        {
        }

        public ChangingEventArgs(object oldValue, object newValue, bool cancel)
            : base(cancel)
        {
            this.oldValue = oldValue;
            this.newValue = newValue;
        }

        // Properties
        public object NewValue
        {
            get
            {
                return this.newValue;
            }
            set
            {
                this.newValue = value;
            }
        }

        public object OldValue
        {
            get
            {
                return this.oldValue;
            }
            protected set
            {
                this.oldValue = value;
            }
        }
    }

 


    public class ChangeEventArgs : EventArgs
    {
        // Fields
        protected bool fCancel;
        protected string fName;
        protected object fValue;

        // Methods
        public ChangeEventArgs()
        {
            this.fName = string.Empty;
        }

        public ChangeEventArgs(string name, object value)
        {
            this.fName = string.Empty;
            this.fName = name;
            this.fValue = value;
        }

        // Properties
        public string Name
        {
            get
            {
                return this.fName;
            }
        }

        public object Value
        {
            get
            {
                return this.fValue;
            }
        }
    }


    public class MaskChangingEventArgs : CancelEventArgs
    {
        // Fields
        private object newValue;
        private object oldValue;

        // Methods
        public MaskChangingEventArgs(object oldValue, object newValue)
            : this(oldValue, newValue, false)
        {
        }

        public MaskChangingEventArgs(object oldValue, object newValue, bool cancel)
            : base(cancel)
        {
            this.oldValue = oldValue;
            this.newValue = newValue;
        }

        // Properties
        public object NewValue
        {
            get
            {
                return this.newValue;
            }
            set
            {
                this.newValue = value;
            }
        }

        public object OldValue
        {
            get
            {
                return this.oldValue;
            }
        }
    }



    public abstract class MaskManager
{
    // Events
    public event EventHandler EditTextChanged;

    public event MaskChangingEventHandler EditTextChanging;

    public event CancelEventHandler LocalEditAction;

    // Methods
    public abstract bool Backspace();
    public virtual void ClearAfterSelectAll()
    {
        this.PrepareForInsertAfterSelectAll();
        if (this.IsSelection)
        {
            this.Delete();
        }
    }

    public abstract bool CursorEnd(bool forceSelection);
    public abstract bool CursorHome(bool forceSelection);
    public bool CursorLeft(bool forceSelection)
    {
        return this.CursorLeft(forceSelection, false);
    }

    public abstract bool CursorLeft(bool forceSelection, bool isNeededKeyCheck);
    public bool CursorRight(bool forceSelection)
    {
        return this.CursorRight(forceSelection, false);
    }

    public abstract bool CursorRight(bool forceSelection, bool isNeededKeyCheck);
    [Obsolete("Use PrepareForCursorMoveAfterSelectAll instead")]
    public void CursorSelectAll()
    {
        this.PrepareForCursorMoveAfterSelectAll();
    }

    public abstract bool CursorToDisplayPosition(int newPosition, bool forceSelection);
    public abstract bool Delete();
    public virtual bool FlushPendingEditActions()
    {
        return false;
    }

    public abstract string GetCurrentEditText();
    public abstract object GetCurrentEditValue();
    public abstract bool Insert(string insertion);
    [Obsolete("Use PrepareForInsertAfterSelectAll instead")]
    public void PrepareForClearChangesAfterSelectAll()
    {
        this.PrepareForInsertAfterSelectAll();
    }

    public virtual void PrepareForCursorMoveAfterSelectAll()
    {
        this.CursorToDisplayPosition(this.DisplayText.Length, false);
        this.CursorToDisplayPosition(0, true);
    }

    public virtual void PrepareForInsertAfterSelectAll()
    {
        this.PrepareForCursorMoveAfterSelectAll();
    }

    protected void RaiseEditTextChanged()
    {
        if (this.EditTextChanged != null)
        {
            this.EditTextChanged(this, EventArgs.Empty);
        }
    }

    protected virtual bool RaiseEditTextChanging(object newEditValue)
    {
        if (this.EditTextChanging != null)
        {
            MaskChangingEventArgs e = new MaskChangingEventArgs(this.GetCurrentEditValue(), newEditValue);
            this.EditTextChanging(this, e);
            return !e.Cancel;
        }
        return true;
    }

    protected bool RaiseModifyWithoutEditValueChange()
    {
        if (this.LocalEditAction != null)
        {
            CancelEventArgs e = new CancelEventArgs();
            this.LocalEditAction(this, e);
            if (e.Cancel)
            {
                return false;
            }
        }
        return true;
    }

    public abstract void SetInitialEditText(string initialEditText);
    public abstract void SetInitialEditValue(object initialEditValue);
    public abstract bool SpinDown();
    public abstract bool SpinUp();
    public abstract bool Undo();

    // Properties
    public abstract bool CanUndo { get; }

    public abstract int DisplayCursorPosition { get; }

    public abstract int DisplaySelectionAnchor { get; }

    public int DisplaySelectionEnd
    {
        get
        {
            if (this.DisplayCursorPosition <= this.DisplaySelectionAnchor)
            {
                return this.DisplaySelectionAnchor;
            }
            return this.DisplayCursorPosition;
        }
    }

    public int DisplaySelectionLength
    {
        get
        {
            if (this.DisplayCursorPosition <= this.DisplaySelectionAnchor)
            {
                return (this.DisplaySelectionAnchor - this.DisplayCursorPosition);
            }
            return (this.DisplayCursorPosition - this.DisplaySelectionAnchor);
        }
    }

    public int DisplaySelectionStart
    {
        get
        {
            if (this.DisplayCursorPosition >= this.DisplaySelectionAnchor)
            {
                return this.DisplaySelectionAnchor;
            }
            return this.DisplayCursorPosition;
        }
    }

    public abstract string DisplayText { get; }

    public abstract bool IsEditValueDifferFromEditText { get; }

    public virtual bool IsFinal
    {
        get
        {
            return false;
        }
    }

    public virtual bool IsMatch
    {
        get
        {
            return true;
        }
    }

    public abstract bool IsPlainTextLike { get; }

    public bool IsSelection
    {
        get
        {
            return (this.DisplayCursorPosition != this.DisplaySelectionAnchor);
        }
    }
}

 

}
